使用 Java Spring Boot 透過 Spring Security 和 JSON Web Token 整合,實現身份驗證機制建立安全的登入和註冊系統。
定義使用者實體類,該類包含使用者的相關資訊。同時實作 Spring Security 的 UserDetails 介面,用於管理和驗證使用者身份。
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "_user")
public class AppUserEntity implements UserDetails {
@Id
@GeneratedValue
private Long id;
@Column(unique = true) //唯一性約束。
private String email;
private String userName;
private String password;
@Enumerated(EnumType.STRING) //將枚舉值作為字串存儲
private AppUserRole userRole;
public AppUserEntity(String userName, String email, String password, AppUserRole userRole) {
this.userName = userName;
this.email = email;
this.password = password;
this.userRole = userRole;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority(userRole.name()));
}
@Override
public String getUsername() {
return email;
}
@Override
public String getPassword() {
return password;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
利用枚舉型別定義角色,用於控制使用者在系統中的權限和許可。
public enum AppUserRole {
USER,
ADMIN
}
使用者 Repository 接口,並使用 Spring Data JPA 來對AppUserEntity進行資料庫操作。
@Repository
public interface AppUserRepository extends JpaRepository<AppUserEntity, Long> {
Optional<AppUserEntity> findByEmail(String email);
}
用於處理身份驗證相關邏輯,註冊並生成JWT進行登入驗證。
@Service
@Slf4j
@AllArgsConstructor
public class AuthenticationService {
private final AppUserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
private final JwtService jwtService;
//註冊
public StatusResponse register(RegisterRequest request){
var user = AppUserEntity.builder()
.userName(request.getUserName())
.password(passwordEncoder.encode(request.getPassword()))
.email(request.getEmail())
.userRole(AppUserRole.USER)
.build();
userRepository.save(user);
return StatusResponse.builder()
.status("註冊成功")
.build();
}
//登入
public AuthenticationResponse login(LoginRequest request) {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.getEmail(),
request.getPassword()
)
);
var user = userRepository.findByEmail(request.getEmail()).orElseThrow();
var jwtToken = jwtService.generateToken(user);
return AuthenticationResponse.builder()
.status("登入成功")
.token(jwtToken)
.build();
}
}
Spring Boot控制器,用於處理與身份驗證相關的 HTTP 請求。
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@Slf4j
public class AuthenticationController {
private final AuthenticationService service;
// 註冊接口
@PostMapping("/register")
public ResponseEntity<StatusResponse> register(
@RequestBody @Validated RegisterRequest request
){
return ResponseEntity.ok(service.register(request));
}
// 登入接口
@PostMapping("/login")
public ResponseEntity<AuthenticationResponse> login(
@RequestBody @Validated LoginRequest request
) {
return ResponseEntity.ok(service.login(request));
}
}
定義用於註冊的請求資料結構。
@Data
public class RegisterRequest {
@NotBlank
private String userName;
@NotBlank
@Email
private String email;
@NotBlank
private String password;
}
定義用於登入的請求資料結構。
@Data
public class LoginRequest {
@NotBlank
@Email
private String email;
@NotBlank
private String password;
}
定義身份驗證回應的資料結構,包括狀態碼和令牌。
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResponse {
private String status;
private String token;
}